package com.baizhi.aspect;

import com.baizhi.annotation.LogAnnotation;
import com.baizhi.dao.LogDao;
import com.baizhi.entity.Admin;
import com.baizhi.entity.Log;
import com.baizhi.util.IPKit;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

@Aspect
@Configuration
public class LogAspect {
    @Resource
    private LogDao logDao;

    /**
     *
     * 因为在增强中要获取注解的值 所以切注解 切 LogAnnotation
     *
     * 代表着只有添加注解的方法 才会被aop
     */
    @After("@annotation(com.baizhi.annotation.LogAnnotation)")
    public void logAfter(JoinPoint joinPoint){
        /**
         * 采集日志数据 封装到对象中
         * 1.日志的主键 自增 不需要关心  pass
         * 2.管理员的id  session
         * 3.日期
         * 4.ip
         * 5.操作内容
         * 6.操作类型
         */
        Log log = new Log();
        /**
         * 从session中获取管理员id
         *
         * ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
         *  HttpServletRequest request = requestAttributes.getRequest();
         *  上面两行代码 可以在项目任何位置拿到request
         *
         * 怎么获取session   request
         */
//        获取request对象
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
//        从session中拿到admin对象


        Admin admin = (Admin) request.getSession().getAttribute("admin");
        if (admin != null){
            log.setAdminId(admin.getId());
        }else {
//            添加0代表没有登录
            log.setAdminId(0);
        }


        /**
         * 日期获取 new Date()
         */
        log.setLogDate(new Date());

        /**
         * ip 如何获取 通过request对象
         * 1.request.getRemoteAddr()  获取远程地址
         * 2.一般情况会采用工具类 ip的获取都是基础功能 公司项目一般都有
         * 我们使用我给的工具类 IPKit
         */
        String ip = IPKit.getIpAddrByRequest(request);
        log.setLogIp(ip);

        /**
         * 操作内容 和 操作类型
         * 难点：不同的方法操作内容不一样
         *  如果是查询上师的方法 获取到的操作内容应该是：查询上师数据 类型是：查询
         *  如果是删除图片的方法 获取到的操作内容应该是：删除图片数据 类型是：删除
         *
         *  解决方案：通过自定义注解
         *  获取注解的值
         *  因为每一个方法上的注解内容都是不一样的 所以获取到内容也不一样的
         *
         *  步骤：
         *
         *  1.在增强中获取被切入的方法上的注解  JoinPoint
         *  2.获取注解的值
         */
//        在增强中可以通过切入点对象  joinPoint 获取到方法 获取注解  获取类 获取到属性
//        通过切入点对象 joinPoint 获取到方法签名对象
//        通过方法签名对象获取到方法对象  signature.getMethod()
//        通过方法对象获取方法上的注解  method.getAnnotation(LogAnnotation.class); 参数为 注解的类对象
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        LogAnnotation annotation = method.getAnnotation(LogAnnotation.class);

//        获取注解的值
        String content = annotation.content();
        String type = annotation.type();

        log.setLogContent(content);
        log.setLogType(type);

        System.out.println(log);
        /**
         * 将日志数据 添加数据库
         */
        logDao.insert(log);
    }
}
